#include "CL_News_pool.h"

CL_News_pool::CL_RSS_Quelle::iNetReturn CL_News_pool::CL_RSS_Quelle::get_response_utf8(std::string& body)
{
    CL_News_pool::CL_RSS_Quelle::iNetReturn iNR;
    body.clear();
    if(is_erroneous) throw last_error;
    Poco::URI uri(url);
    Poco::Net::HTTPClientSession client(uri.getHost(), uri.getPort());
    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.toString());//uri.getPath()
    request.setHost(uri.getHost());
    request.add("User-Agent",progname);
    if(!last_modified.empty())
        request.add("If-Modified-Since",last_modified);
    request.add("Accept-Encoding","gzip,deflate");
#warning TODO (markus#1#): application/rdf+xml, and application/atom+xml sollten berücksichtigt werden
    std::string a = accepted_mime_types + ",*/*;q=0.1"; //crazy: But I found some sites which give me the right mime type while refusing to interprest Accept: correctly like www.faz.net
    request.add("Accept",a);
    try
    {
        mylog("CL_News_pool.CL_RSS_Quelle.get_response_utf8","Request sent to: "+url, LOG_DEBUG);
        client.sendRequest(request);
    }
    catch(Poco::Net::HostNotFoundException e)
    {
#warning TODO (markus#1#): Logging fehlt
        is_erroneous=true;
        last_error.set_error("Host not found");
        throw last_error;
    }
    catch(Poco::Net::DNSException e)
    {
#warning TODO (markus#1#): Logging fehlt
        is_erroneous=true;
        last_error.set_error("DNS Error");
        throw last_error;
    }
    Poco::Net::HTTPResponse response;
    std::istream& responsestream = client.receiveResponse(response);
    iNR.status=response.getStatus();
    switch (iNR.status)
    {
    case Poco::Net::HTTPResponse::HTTP_OK:
        process_status_200(iNR, response, body, client, responsestream);
        break;
    case Poco::Net::HTTPResponse::HTTP_NOT_MODIFIED:
        iNR.hashvalue=last_feed_hash;
        break;
    default:
        std::ostringstream oe;
        oe<<"HTTP Status code: "<<iNR.status<<" for request to "<<url<<std::endl;
        oe.flush();
        mylog("CL_News_pool::CL_RSS_Quelle::get_response_utf8", oe.str(), LOG_WARNING);
        if(LOG_MASK(LOG_DEBUG)&message_level)
        {
            std::string filename=write_request_response_2_file(request, response);
            std::string e="Request/Response to "+url+" written to file "+filename;
            mylog("CL_News_pool::CL_RSS_Quelle::get_response_utf8", e);
        }
    }
    return iNR;
}


void CL_News_pool::CL_RSS_Quelle::process_status_200(CL_News_pool::CL_RSS_Quelle::iNetReturn& iNR,
        Poco::Net::HTTPResponse& response,
        std::string& body, Poco::Net::HTTPClientSession& client,
        std::istream& responsestream)
{
    std::istream* istream=&responsestream;
    Poco::InflatingInputStream zlib(responsestream, Poco::InflatingStreamBuf::STREAM_ZLIB);
    Poco::InflatingInputStream gzip(responsestream, Poco::InflatingStreamBuf::STREAM_GZIP);
    const std::string& content_type = response.get("Content-Type");
    std::string encoding_type=std::string("");
    /* keep the date of last modification in member; next response may be faster*/
    last_modified.clear();
    if(response.has("Last-Modified")) last_modified=response.get("Last-Modified");
    if(response.has("Content-Encoding"))
    {
        encoding_type=response.get("Content-Encoding");
        if(encoding_type=="gzip")
        {
            istream=&gzip;
        }
        else
        {
            if(encoding_type=="deflate")
                istream=&zlib;
            else
            {
                mylog("CL_News_pool::CL_RSS_Quelle::process_status_200","Request sent to "+url+": got response with wrong compression",LOG_CRIT);
                iNR.internal_error=INT_ERR_WRONG_COMPRESSION;
                return;
            }
        }
    }

#warning TODO (markus#1#): clean up string handling by MessageHeader.SplitParameter etc
    std::string scharset = "ISO 8859-1";
    std::string content_type_without_attr = content_type.substr(0,content_type.find(";"));
    if(CL_RSS_Quelle::accepted_mime_types.find(content_type_without_attr)==CL_RSS_Quelle::accepted_mime_types.npos)
    {
        is_erroneous=true;
        last_error.set_error("Content type not accepted.");
        throw last_error;
    }
    size_t icharset=content_type.find("charset=");
    if (icharset!=content_type.npos)
    {
        icharset+=8;
        scharset=content_type.substr(icharset);
        size_t ionlyattrib = scharset.find(";");
        scharset=scharset.substr(0,ionlyattrib);
    };
    char c;
    while (istream->get(c))
    {
        body+=c;
    }
    UnicodeString US(body.c_str(),scharset.c_str());
    body.clear();
    US.toUTF8String(body);
    iNR.hashvalue=myhash(body);
}


